﻿using Microsoft.Win32;
using System;
using System.IO;
using System.Text.RegularExpressions;
using System.Threading;

namespace Install
{
    class ProgramUnintall
    {
        private string pathRoot;

        public ProgramUnintall()
        {
            Thread thread = new Thread(StartUnstall);
            thread.IsBackground = true;
            thread.Start();
        }

        void StartUnstall()
        {
            MainWindow.instance.Doing = true;
            try
            {
                MainWindow.instance.OutputMsg("开始卸载...");
                //ShutDownService();
                ShutDownNotify();
                Thread.Sleep(500);
                DeleteRegex();
                Thread.Sleep(500);
                DeleteFiles();
                MainWindow.instance.OutputMsg("程序卸载完成。\n");
            }
            catch (Exception e)
            {
                MainWindow.instance.OutputErr(e.Message);
                throw e;
            }
            Thread.Sleep(300);
            MainWindow.instance.Doing = false;
        }

        private void ShutDownNotify()
        {
            System.Diagnostics.Process[] pro = System.Diagnostics.Process.GetProcesses();//获取已开启的所有进程
            for (int i = 0; i < pro.Length; i++)//遍历所有查找到的进程
            {
                //判断此进程是否是要查找的进程
                if (pro[i].ProcessName.ToString().ToLower() == "sfjdtray")
                {
                    pro[i].Kill();//结束进程
                    MainWindow.instance.OutputMsg("残留进程已经关闭。");
                }
            }
        }

        /// <summary>
        /// 删除目录及子目录的所有文件
        /// </summary>
        public void DeleteFiles()
        {
            if(pathRoot == string.Empty)
            {
                pathRoot = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles) + @"\SFJDManagement";
            }
            MainWindow.instance.OutputMsg("开始删除文件...");
            try
            {
                DirectoryInfo dir = new DirectoryInfo(pathRoot);
                FileSystemInfo[] fileinfo = dir.GetFileSystemInfos();  //返回目录中所有文件和子目录
                foreach (FileSystemInfo i in fileinfo)
                {
                    if (i is DirectoryInfo)            //判断是否文件夹
                    {
                        DirectoryInfo subdir = new DirectoryInfo(i.FullName);
                        subdir.Delete(true);          //删除子目录和文件
                    }
                    else
                    {
                        
                        if(Regex.IsMatch(i.Name, "^.*\\.xml$"))
                        {
                            //MainWindow.instance.OutputMsg("忽略： " + i.Name);
                            continue;
                        }
                        //switch (i.Name.ToLower())
                        //{
                        //    case "config.xml":
                        //        continue;
                        //    case "temp.xml":
                        //        continue;
                        //}
                        int times = 0;
                        while (IsFileInUse(i.FullName))
                        {
                            times++;
                            MainWindow.instance.OutputErr(i.Name + "文件被占用，请稍等...");
                            Thread.Sleep(1000);
                            if(times > 10)
                            {
                                break;
                            }
                        }
                        File.Delete(i.FullName);      //删除指定文件
                        MainWindow.instance.OutputMsg("删除： " + i.Name);
                    }
                }
            }
            catch(Exception e)
            {
                MainWindow.instance.OutputErr(this.GetType().ToString() + ": " + e.Message);
                throw e;
            }
            MainWindow.instance.OutputMsg("文件已删除。");
        }

        /// <summary>
        /// 关闭并删除系统服务
        /// </summary>
        private void ShutDownService()
        {
            try
            {
                MainWindow.instance.OutputMsg("正在卸载Windows服务...");
                if(new ServiceHelper().UninstallService("SFJDService"))
                {
                    MainWindow.instance.OutputMsg("Windows服务已经卸载。");
                }
            }
            catch
            {
                MainWindow.instance.OutputErr("Windows服务卸载失败。");
            }
            finally
            {
                System.Diagnostics.Process[] pro = System.Diagnostics.Process.GetProcesses();//获取已开启的所有进程
                for (int i = 0; i < pro.Length; i++)//遍历所有查找到的进程
                {
                    //判断此进程是否是要查找的进程
                    if (pro[i].ProcessName.ToString().ToLower() == "sfjdservice")
                    {
                        pro[i].Kill();//结束进程
                        MainWindow.instance.OutputMsg("残留进程已经关闭。");
                    }
                }
            }
        }

        /// <summary>
        /// 检查文件是否被占用
        /// </summary>
        /// <param name="fileName"></param>
        /// <returns></returns>
        private bool IsFileInUse(string fileName)
        {
            bool inUse = true;
            FileStream fs = null;
            try
            {
                fs = new FileStream(fileName, FileMode.Open, FileAccess.Read,
                FileShare.None);
                inUse = false;
            }
            catch
            {
            }
            finally
            {
                if (fs != null)
                    fs.Close();
            }
            return inUse;//true表示正在使用,false没有使用
        }

        /// <summary>
        /// 删除注册表项
        /// </summary>
        private void DeleteRegex()
        {
            RegistryKey regRoot = Registry.CurrentUser;
            RegistryHelper reg = new RegistryHelper();
            pathRoot = reg.GetRegistryData(regRoot, "SOFTWARE\\SFJDManagement\\", "RootPath");

            MainWindow.instance.OutputMsg("正在删除注册表...");
            try
            {
                reg.DeleteRegist(regRoot, "SOFTWARE", "SFJDManagement");
                MainWindow.instance.OutputMsg("注册表已删除。");
                DeleteRegex2();
            }
            catch (Exception e)
            {
                MainWindow.instance.OutputErr(e.Message);
                throw e;
            }
        }

        private void DeleteRegex2()
        {
            RegistryKey regRoot = Registry.LocalMachine;
            RegistryHelper reg = new RegistryHelper();
            pathRoot = reg.GetRegistryData(regRoot, "SOFTWARE\\SFJDManagement\\", "RootPath");

            MainWindow.instance.OutputMsg("正在删除注册表...");
            try
            {
                reg.DeleteRegist(regRoot, "SOFTWARE", "SFJDManagement");
                MainWindow.instance.OutputMsg("注册表已删除。");
            }
            catch (Exception e)
            {
                MainWindow.instance.OutputErr(e.Message);
                throw e;
            }
        }
    }
}
